﻿using RotovapPlatform.Domain.Business.Machine.Enums;
using RotovapPlatform.Domain.Business.Recipes.Entities;
using RotovapPlatform.Domain.Business.Storage.Entities;
using RotovapPlatform.Domain.Business.Storage.Enums;
using RotovapPlatform.Domain.Common;
using static RotovapPlatform.Domain.Business.Machine.Enums.ExperimentConfigEnums;
using System;
using System.Threading.Tasks;

namespace RotovapPlatform.Domain.Services.Experiments
{
	/// <summary>
	/// 实验阶段变更事件参数
	/// </summary>
	public class ExperimentStageChangedEventArgs : EventArgs
	{
		/// <summary>
		/// 实验ID
		/// </summary>
		public Guid ExperimentId { get; }

		/// <summary>
		/// 实验阶段
		/// </summary>
		public ExperimentStage Stage { get; }

		/// <summary>
		/// 构造函数
		/// </summary>
		public ExperimentStageChangedEventArgs(Guid experimentId, ExperimentStage stage)
		{
			ExperimentId = experimentId;
			Stage = stage;
		}
	}

	/// <summary>
	/// 实验子阶段变更事件参数
	/// </summary>
	public class ExperimentSubStageChangedEventArgs : EventArgs
	{
		/// <summary>
		/// 实验ID
		/// </summary>
		public Guid ExperimentId { get; }

		/// <summary>
		/// 实验阶段
		/// </summary>
		public ExperimentStage Stage { get; }

		/// <summary>
		/// 实验子阶段
		/// </summary>
		public ExperimentSubStage SubStage { get; }

		/// <summary>
		/// 构造函数
		/// </summary>
		public ExperimentSubStageChangedEventArgs(Guid experimentId, ExperimentStage stage, ExperimentSubStage subStage)
		{
			ExperimentId = experimentId;
			Stage = stage;
			SubStage = subStage;
		}
	}

	/// <summary>
	/// 实验流程领域服务接口
	/// 负责实验工艺流程的具体实现，根据应用层的大步骤，实现具体的小步骤
	/// </summary>
	public interface IExperimentProcessDomainService : IDisposable
	{
		/// <summary>
		/// 当前实验阶段变更事件
		/// </summary>
		event EventHandler<ExperimentStageChangedEventArgs> ExperimentStageChanged;

		/// <summary>
		/// 当前实验子阶段变更事件
		/// </summary>
		event EventHandler<ExperimentSubStageChangedEventArgs> ExperimentSubStageChanged;

		/// <summary>
		/// 获取当前实验ID
		/// </summary>
		Guid? CurrentExperimentId { get; }

		/// <summary>
		/// 获取当前实验阶段
		/// </summary>
		ExperimentStage? CurrentStage { get; }

		/// <summary>
		/// 获取当前实验子阶段
		/// </summary>
		ExperimentSubStage? CurrentSubStage { get; }

		/// <summary>
		/// 从特定阶段恢复实验
		/// </summary>
		/// <param name="experiment">实验对象</param>
		/// <param name="resumeStage">要恢复的阶段</param>
		/// <param name="resumeSubStage">要恢复的子阶段，为null时从阶段起始点开始</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> ResumeExperimentAsync(Experiment experiment, ExperimentStage resumeStage, ExperimentSubStage? resumeSubStage = null);

		#region 机械手操作方法

		///// <summary>
		///// 瓶子搬运
		///// </summary>
		///// <param name="transportParams">搬运参数</param>
		///// <returns>操作结果</returns>
		//Task<OperationResult> TransportVialAsync(VialTransportParams transportParams);

		///// <summary>
		///// 更换夹爪
		///// </summary>
		///// <param name="targetGripper">目标夹爪类型</param>
		///// <returns>操作结果</returns>
		//Task<OperationResult> ChangeGripperAsync(int targetGripper);

		///// <summary>
		///// 开盖操作
		///// </summary>
		///// <param name="vialParams">瓶子参数</param>
		///// <returns>操作结果</returns>
		//Task<OperationResult> OpenCapAsync(VialParams vialParams);

		///// <summary>
		///// 关盖操作
		///// </summary>
		///// <param name="vialParams">瓶子参数</param>
		///// <returns>操作结果</returns>
		//Task<OperationResult> CloseCapAsync(VialParams vialParams);

		#endregion


		#region 工作站操作


		/// <summary>
		/// 插管操作
		/// </summary>
		/// <param name="tubeParams">插管参数</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> InsertTubeAsync(TubeParams tubeParams);

		/// <summary>
		/// 撤管操作
		/// </summary>
		/// <param name="tubeParams">撤管参数</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> WithdrawTubeAsync(TubeParams tubeParams);

		#endregion

		#region 旋蒸参数控制

		/// <summary>
		/// 设置加热参数
		/// </summary>
		/// <param name="heatingParams">加热参数</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> SetHeatingParametersAsync(HeatingParams heatingParams);

		/// <summary>
		/// 设置真空参数
		/// </summary>
		/// <param name="vacuumParams">真空参数</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> SetVacuumParametersAsync(VacuumParams vacuumParams);

		/// <summary>
		/// 设置旋转参数
		/// </summary>
		/// <param name="rotParams">旋转参数</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> SetRotationParametersAsync(RotationParams rotParams);

		#endregion

		#region 清洗方法

		/// <summary>
		/// 系统清洗
		/// </summary>
		/// <param name="cleaningParams">清洗参数</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> CleanSystemAsync(CleaningParams cleaningParams);

		#endregion

		#region 设备控制方法

		/// <summary>
		/// 设置设备模式
		/// </summary>
		/// <param name="mode">设备模式</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> SetDeviceModeAsync(DeviceEnums.DeviceMode mode);

		/// <summary>
		/// 获取设备状态
		/// </summary>
		/// <returns>设备状态</returns>
		Task<DeviceEnums.DeviceStatus> GetDeviceStatusAsync();

		/// <summary>
		/// 执行紧急停止
		/// </summary>
		/// <returns>操作结果</returns>
		Task<OperationResult> ExecuteEmergencyStopAsync();

		/// <summary>
		/// 重置设备
		/// </summary>
		/// <returns>操作结果</returns>
		Task<OperationResult> ResetDeviceAsync();

		#endregion

		/// <summary>
		/// 处理实验错误
		/// </summary>
		/// <param name="experiment">实验</param>
		/// <param name="errorMessage">错误信息</param>
		/// <param name="attemptRecovery">是否尝试恢复</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> HandleExperimentErrorAsync(
			Experiment experiment,
			string errorMessage,
			bool attemptRecovery = true);

		/// <summary>
		/// 执行物料&条件准备阶段
		/// </summary>
		/// <param name="experiment">实验对象</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> ExecuteMaterialAndConditionPreparationAsync(Experiment experiment);

		/// <summary>
		/// 执行旋蒸阶段
		/// </summary>
		/// <param name="experiment">实验对象</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> ExecuteRotaryEvaporationAsync(Experiment experiment);

		/// <summary>
		/// 执行旋蒸残液处理阶段
		/// </summary>
		/// <param name="experiment">实验对象</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> ExecuteEvaporationResidueProcessingAsync(Experiment experiment);

		/// <summary>
		/// 执行冷凝液处理阶段
		/// </summary>
		/// <param name="experiment">实验对象</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> ExecuteCondensateProcessingAsync(Experiment experiment);

		/// <summary>
		/// 执行清洗阶段
		/// </summary>
		/// <param name="experiment">实验对象</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> ExecuteCleaningAsync(Experiment experiment);

		/// <summary>
		/// 执行实验暂停操作
		/// </summary>
		/// <returns>操作结果</returns>
		Task<OperationResult> ExecutePauseAsync();

		/// <summary>
		/// 执行设备初始化
		/// </summary>
		/// <returns>操作结果</returns>
		Task<OperationResult> InitializeDevicesAsync();
	}

	#region 参数类型定义

	/// <summary>
	/// 瓶子搬运参数
	/// </summary>
	public class VialTransportParams
	{
		/// <summary>
		/// 瓶子ID
		/// </summary>
		public Guid VialId { get; set; }

		/// <summary>
		/// 源位置
		/// </summary>
		public LocationCode SourceLocation { get; set; }

		/// <summary>
		/// 源位置编号
		/// </summary>
		public int SourcePosition { get; set; }

		/// <summary>
		/// 目标位置
		/// </summary>
		public LocationCode TargetLocation { get; set; }

		/// <summary>
		/// 目标位置编号
		/// </summary>
		public int TargetPosition { get; set; }

		/// <summary>
		/// 瓶子类型
		/// </summary>
		public ItemType VialType { get; set; }

		/// <summary>
		/// 操作类型
		/// </summary>
		public TransportOperationType OperationType { get; set; }
	}

	/// <summary>
	/// 瓶子参数
	/// </summary>
	public class VialParams
	{
		/// <summary>
		/// 瓶子ID
		/// </summary>
		public Guid VialId { get; set; }

		/// <summary>
		/// 位置
		/// </summary>
		public LocationCode Location { get; set; }

		/// <summary>
		/// 位置编号
		/// </summary>
		public int Position { get; set; }

		/// <summary>
		/// 瓶子类型
		/// </summary>
		public ItemType VialType { get; set; }
	}

	/// <summary>
	/// 旋蒸瓶参数
	/// </summary>
	public class FlaskParams
	{
		/// <summary>
		/// 旋蒸瓶ID
		/// </summary>
		public Guid FlaskId { get; set; }

		/// <summary>
		/// 位置
		/// </summary>
		public LocationCode Location { get; set; }

		/// <summary>
		/// 位置编号
		/// </summary>
		public int Position { get; set; }
	}

	/// <summary>
	/// 液体参数
	/// </summary>
	public class LiquidParams
	{
		/// <summary>
		/// 源瓶ID
		/// </summary>
		public Guid SourceVialId { get; set; }

		/// <summary>
		/// 目标瓶ID
		/// </summary>
		public Guid TargetVialId { get; set; }

		/// <summary>
		/// 泵送体积
		/// </summary>
		public double Volume { get; set; }

		/// <summary>
		/// 体积单位
		/// </summary>
		public string VolumeUnit { get; set; }

		/// <summary>
		/// 泵送速率
		/// </summary>
		public double FlowRate { get; set; }

		/// <summary>
		/// 泵送类型
		/// </summary>
		public DeviceEnums.DeviceComponentType PumpType { get; set; }
	}

	/// <summary>
	/// 阀门参数
	/// </summary>
	public class ValveParams
	{
		/// <summary>
		/// 阀门ID
		/// </summary>
		public string ValveId { get; set; }

		/// <summary>
		/// 阀门位置
		/// </summary>
		public int Position { get; set; }
	}

	/// <summary>
	/// 插管参数
	/// </summary>
	public class TubeParams
	{
		/// <summary>
		/// 瓶子ID
		/// </summary>
		public Guid VialId { get; set; }

		/// <summary>
		/// 位置
		/// </summary>
		public LocationCode Location { get; set; }

		/// <summary>
		/// 位置编号
		/// </summary>
		public int Position { get; set; }

		/// <summary>
		/// 插管深度
		/// </summary>
		public double Depth { get; set; }

		/// <summary>
		/// 插管类型
		/// </summary>
		public TubeType TubeType { get; set; }
	}

	/// <summary>
	/// 加热参数
	/// </summary>
	public class HeatingParams
	{
		/// <summary>
		/// 目标温度
		/// </summary>
		public double TargetTemperature { get; set; }

		/// <summary>
		/// 加热速率
		/// </summary>
		public double HeatingRate { get; set; }

		/// <summary>
		/// 加热设备类型
		/// </summary>
		public DeviceEnums.DeviceComponentType DeviceType { get; set; }
	}

	/// <summary>
	/// 真空参数
	/// </summary>
	public class VacuumParams
	{
		/// <summary>
		/// 目标真空度
		/// </summary>
		public double TargetVacuum { get; set; }

		/// <summary>
		/// 抽真空速率
		/// </summary>
		public double VacuumRate { get; set; }
	}

	/// <summary>
	/// 旋转参数
	/// </summary>
	public class RotationParams
	{
		/// <summary>
		/// 目标转速
		/// </summary>
		public double TargetSpeed { get; set; }

		/// <summary>
		/// 加速度
		/// </summary>
		public double Acceleration { get; set; }

		/// <summary>
		/// 旋转模式
		/// </summary>
		public RotationMode Mode { get; set; }
	}

	/// <summary>
	/// 清洗参数
	/// </summary>
	public class CleaningParams
	{
		/// <summary>
		/// 清洗液瓶ID
		/// </summary>
		public Guid CleaningFlaskId { get; set; }

		/// <summary>
		/// 废液瓶ID
		/// </summary>
		public Guid WasteFlaskId { get; set; }

		/// <summary>
		/// 清洗循环次数
		/// </summary>
		public int CleaningCycles { get; set; }

		/// <summary>
		/// 每次清洗时间（秒）
		/// </summary>
		public int CleaningTimeSeconds { get; set; }

		/// <summary>
		/// 清洗类型
		/// </summary>
		public CleaningType CleaningType { get; set; }
	}

	#endregion

	#region 枚举类型定义

	/// <summary>
	/// 搬运操作类型
	/// </summary>
	public enum TransportOperationType
	{
		/// <summary>
		/// 入库
		/// </summary>
		StoreIn,

		/// <summary>
		/// 出库
		/// </summary>
		TakeOut,

		/// <summary>
		/// 移动
		/// </summary>
		Move
	}

	/// <summary>
	/// 插管类型
	/// </summary>
	public enum TubeType
	{
		/// <summary>
		/// 液体输送管
		/// </summary>
		LiquidTransferTube,

		/// <summary>
		/// 气体输送管
		/// </summary>
		GasTransferTube
	}

	/// <summary>
	/// 旋转模式
	/// </summary>
	public enum RotationMode
	{
		/// <summary>
		/// 恒速模式
		/// </summary>
		ConstantSpeed,

		/// <summary>
		/// 力矩模式
		/// </summary>
		TorqueMode
	}

	/// <summary>
	/// 清洗类型
	/// </summary>
	public enum CleaningType
	{
		/// <summary>
		/// 管路清洗
		/// </summary>
		TubeCleaning,

		/// <summary>
		/// 旋蒸瓶清洗
		/// </summary>
		FlaskCleaning,

		/// <summary>
		/// 全系统清洗
		/// </summary>
		SystemCleaning
	}

	#endregion
}